package org.weasel.controllers;

import java.util.ArrayList;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.graphics.Point;
import org.weasel.business.Developer;
import org.weasel.business.Iteration;
import org.weasel.business.Project;
import org.weasel.business.Release;
import org.weasel.business.UserStory;
import org.weasel.models.Model;
import org.weasel.wizards.CreateDeveloperWizard;

public class DeveloperViewController {
	private static DeveloperViewController instance = null;
	private ApplicationController appController;
	private DeveloperEditViewController developerEditViewController;
	private Model model;
	private TableViewer viewer;
	
	private DeveloperViewController(){
		developerEditViewController = DeveloperEditViewController.instance();
		developerEditViewController.setController(this);
	}
	
	public static DeveloperViewController instance(){
		if(instance == null)
			instance = new DeveloperViewController();
		return instance;
	}

	public void setModel(Model model) {
		this.model = model;
	}

	public void setApplicationController(ApplicationController controller) {
		this.appController = controller;
	}

	public void setViewer(TableViewer viewer) {
		this.viewer = viewer;
	}
	
	public ArrayList<Developer> displayDeveloperViewContent(){
		return model.getCompany().getDevelopers();
	}

	public void executeDoubleClick() {
		developerEditViewController.setDeveloper(getSelectedListObject());
		developerEditViewController.showDeveloperEditView();
	}
	
	public void refreshViewer(){
		viewer.refresh();
	}
	
	public void showDeveloperWizard() {
		CreateDeveloperWizard wizard = new CreateDeveloperWizard(model);
		if (wizard != null) {
			WizardDialog dialog = new WizardDialog(viewer.getControl().getShell(), wizard);
			dialog.setPageSize(new Point(450, 250));
	        dialog.open();
	        //TODO This should be changed such that only one of the two is called
	        appController.changesOccured();
	        appController.updateViews();
		}
		viewer.refresh();
	}
	
	private Developer getSelectedListObject() {
		try{
			ISelection selection = viewer.getSelection();
			Developer selectedListObj = (Developer) ((IStructuredSelection) selection).getFirstElement();
			return selectedListObj;	
		}catch (Exception e){
			System.out.println("Exception caught: Navigator.getSelectedTreeObject()");
			return null;
		}
	}

	public void deleteDeveloper() {
		boolean everythingFine = true;
		String errorReason = "";
		Developer selectedDeveloper = getSelectedListObject();
		
		//all projects + user-stories have to be scanned if the developer is involved, moreover
		//if it is the only developer of a project, the deletion should be prohibited by warning the user
		ArrayList<Project> projects = model.getCompany().getProjects();
		for (Project project : projects) {
			if(project.getDeveloper(selectedDeveloper.getId())!=null){
				//developer is involded in this project --> check if it is the only one
				if(project.getDevelopers().size()<=1){
					everythingFine = false; //prohibit deletion
					errorReason = "The selected developer is the only developer of project \"" + project.getName() + "\" which is not allowed. In the case" +
							" you still want to remove it, please add another developer to that project!";
				}else{
					project.removeDeveloper(selectedDeveloper.getId());
					
					//scan all user-stories (unscheduled + iterations + all release unscheduled) for that developer
					ArrayList<UserStory> userStories = project.getUnscheduled().getUserStories();
					ArrayList<Release> releases = project.getReleases();
					for (Release release : releases) {
						userStories.addAll(release.getUnscheduled().getUserStories());
						ArrayList<Iteration> iterations = release.getIterations();
						for (Iteration iteration : iterations) {
							userStories.addAll(iteration.getUserStories());
						}
					}
					
					//now scan for the participation of the selected developer and remove it
					for (UserStory userstory : userStories) {
						if(userstory.getDeveloper(selectedDeveloper.getId())!=null)
							userstory.removeDeveloper(selectedDeveloper.getId());
					}
				}
			}
		}
		if(everythingFine){
			if(MessageDialog.openConfirm(viewer.getControl().getShell(), "Confirm", "Do You want to delete developer \"" + selectedDeveloper.getName() + "\"?")){
				model.getCompany().removeDeveloper(selectedDeveloper.getId());
				refreshViewer();
				
				appController.updateViews();
			}
		}else{
			MessageDialog.openError(viewer.getControl().getShell(), "Error deleting developer", "There was an error when deleting the developer \"" + selectedDeveloper.getName() + "\"\nReason:\n" + errorReason);
		}
	}

}
